/**
 *Copyright (c) 2024 watereyes
 * safetymanagement is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan
 * PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */
package com.koron.scene.service.impl;


import com.google.gson.Gson;
import com.koron.common.bean.DepartmentTreeBean;
import com.koron.common.bean.StaffBean;
import com.koron.common.dfs.FastDFSClientWrapper;
import com.koron.common.domain.DataBean;
import com.koron.common.generator.DefaultIdGenerator;
import com.koron.common.util.DocConverterUtils;
import com.koron.common.web.Util;
import com.koron.scene.domain.HealthDocumentation;
import com.koron.scene.mapper.HealthDocumentationMapper;
import com.koron.scene.service.api.HealthDocumentationService;
import com.koron.scene.utils.BusinessCode;
import com.koron.system.domain.DictData;
import com.koron.system.service.api.DictDataService;
import org.apache.commons.lang3.StringUtils;
import org.koron.ebs.mybatis.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class HealthDocumentationServiceImpl implements HealthDocumentationService {

    private final static  Logger logger = LoggerFactory.getLogger(HealthDocumentationServiceImpl.class);

    @Autowired
    private FastDFSClientWrapper clientWrapper;

    @Autowired
    private DocConverterUtils docConverterUtils;

    @Autowired
    private Util util;

    @Autowired
    private DictDataService dataService;

    @Override
    public DataBean<HealthDocumentation> fetchDocuments(String corpCode, String name,
                                                        String documentationTypeId, String deptCode,
                                                        Integer start, Integer rows) {
        if (logger.isDebugEnabled()) {
            logger.debug("corpCode = {}, name = {}", corpCode, name);
        }
        try (SessionFactory factory = new SessionFactory()) {
            HealthDocumentationMapper mapper = factory.getMapper(HealthDocumentationMapper.class);
            List<HealthDocumentation> healthList = mapper.queryByCondition(corpCode, name, documentationTypeId, deptCode, start, rows);
            Integer total = mapper.countByCondition(corpCode, name, documentationTypeId, deptCode);
            DataBean<HealthDocumentation> dataBean = new DataBean<>();
            dataBean.setList(healthList);
            dataBean.setPageSize(rows);
            dataBean.setTotalNumber(total);
            dataBean.setTotalPage(total > rows ? (total % rows == 0 ? total / rows : total / rows + 1) : 1);
            dataBean.setPageNo(start / rows + 1);
            return dataBean;
        }
    }

    @Override
    public HealthDocumentation fetchOne(String id) {
        if (logger.isDebugEnabled()) {
            logger.debug("id = {}", id);
        }
        try (SessionFactory factory = new SessionFactory()) {
            return factory.getMapper(HealthDocumentationMapper.class).queryOne(id);
        }
    }

    @Override
    public Boolean batchDetele(List<String> idList) {
        try (SessionFactory factory = new SessionFactory()) {
            return factory.getMapper(HealthDocumentationMapper.class).batchDetele(idList) >= 0;
        }
    }

    @Override
    public Integer persist(HealthDocumentation document, MultipartFile[] files, String delFileAddress, String keepFileAddress, String delPreFileAddress, String keepPreFileAddress) {
        List<String> addAddressList = new ArrayList<>();
        List<String> keepAddressList = new ArrayList<>();
        List<String> addPreAddressList = new ArrayList<>();
        List<String> keepPreAddressList = new ArrayList<>();
        try (SessionFactory factory = new SessionFactory()) {
            Integer start = null, rows = null;
            HealthDocumentation dest = null;
            HealthDocumentationMapper mapper = factory.getMapper(HealthDocumentationMapper.class);
            List<HealthDocumentation> documents = mapper.queryByCondition(document.getCorpCode(), document.getName(),
                    null, null, start, rows);
            if (documents != null && !documents.isEmpty()) {
                documents = documents.stream().filter(d -> d.getName().equals(document.getName())).collect(Collectors.toList());
                dest = !documents.isEmpty() ? documents.get(0) : null;
            }
            if (StringUtils.isBlank(document.getId())) {
                if (dest != null) {
                    return BusinessCode.HEALTH_DOCUMENTATION_NAME_DUP.getCode();
                }
                document.setId(DefaultIdGenerator.getInstance().generateLongId());
                transfer(files, keepFileAddress, addAddressList, keepAddressList, keepPreFileAddress, addPreAddressList, keepPreAddressList);
                document.setAttachment(keepAddressList.size() <= 0 ? null : new Gson().toJson(keepAddressList));
                document.setPreviewAttachment(keepPreAddressList.size() <= 0 ? null : new Gson().toJson(keepPreAddressList));
                if (mapper.insert(document) > 0) {
                    return BusinessCode.SUCCESS.getCode();
                }
            } else {
                if (dest != null && !dest.getId().equals(document.getId())) {
                    return BusinessCode.DEVICE_NAME_DUP.getCode();
                }
                transfer(files, keepFileAddress, addAddressList, keepAddressList, keepPreFileAddress, addPreAddressList, keepPreAddressList);
                document.setAttachment(keepAddressList.size() <= 0 ? null : new Gson().toJson(keepAddressList));
                document.setPreviewAttachment(keepPreAddressList.size() <= 0 ? null : new Gson().toJson(keepPreAddressList));
                if (mapper.update(document) > 0) {
                    if (StringUtils.isNotBlank(delFileAddress)) {
                        String[] delArray = delFileAddress.split("[,，]");
                        removeAttachment(Arrays.asList(delArray));
                    }
                    if (StringUtils.isNotBlank(delPreFileAddress)) {
                        String[] delArray = delFileAddress.split("[,，]");
                        removeAttachment(Arrays.asList(delArray));
                    }
                    return BusinessCode.SUCCESS.getCode();
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            removeAttachment(addAddressList);
            removeAttachment(addPreAddressList);
            logger.error(e.getMessage(),e);
        }
        return BusinessCode.EXCEPTION.getCode();
    }

    @Override
    public List<HealthDocumentation> exportList(StaffBean user, String corpCode, String name, String documentationTypeId, String manager) {
        if (logger.isDebugEnabled()) {
            logger.debug("corpCode = {}, name = {}", corpCode, name);
        }
        try (SessionFactory factory = new SessionFactory()) {
            HealthDocumentationMapper mapper = factory.getMapper(HealthDocumentationMapper.class);
            List<HealthDocumentation> healthList = mapper.queryByCondition(corpCode, name, documentationTypeId, manager, null, null);
            if (null != healthList && healthList.size() > 0) {
                Map<String, DictData> cacheMap = dataService.getCacheMap();
                healthList.forEach(bean->{
                    if (StringUtils.isNotEmpty(bean.getCorpCode())) {
                        List<DepartmentTreeBean> departmentTreeBeanList = (List<DepartmentTreeBean>) util.depttree(bean.getCorpCode(), 0).getData();
                        Map<String, String> map = departmentTreeBeanList.stream().collect(Collectors.toMap(DepartmentTreeBean::getDepartmentCode, DepartmentTreeBean::getName));
                        bean.setCorpName((departmentTreeBeanList == null || departmentTreeBeanList.size() <= 0)
                                ? null : map.get(bean.getCorpCode()));
                    }
                    if (StringUtils.isNotEmpty(bean.getDocumentationTypeId())) {
                        DictData element = cacheMap.get(bean.getDocumentationTypeId());
                        bean.setDocumentationType(element != null ? element.getDictLabel() : "");
                    }
                });
            }
            return healthList;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            return null;
        }

    }


    private void transfer(MultipartFile[] files, String keepFileAddress, List<String> addAddressList, List<String> keepAddressList, String keepPreFileAddress, List<String> addPreAddressList, List<String> keepPreAddressList) throws Exception {
        String[] keepAddressArray = StringUtils.isBlank(keepFileAddress) ? null : keepFileAddress.split("[,，]");
        if (keepAddressArray != null && keepAddressArray.length > 0) {
            keepAddressList.addAll(Arrays.asList(keepAddressArray));
        }
        String[] keepPreAddressArray = StringUtils.isBlank(keepPreFileAddress) ? null : keepPreFileAddress.split("[,，]");
        if (keepPreAddressArray != null && keepPreAddressArray.length > 0) {
            keepPreAddressList.addAll(Arrays.asList(keepPreAddressArray));
        }
        // 上传图片
        if (null != files) {
            for (MultipartFile file : files) {
                String url = clientWrapper.uploadFile(file);
                String filpath = url + "#" + file.getOriginalFilename();
                addAddressList.add(filpath);
                String filePrePath = docConverterUtils.converterUpdate(file);
                if (filePrePath != null) {
                    addPreAddressList.add(filePrePath);
                } else {
                    addPreAddressList.add(filpath);
                }
            }
            keepAddressList.addAll(addAddressList);
            keepPreAddressList.addAll(addPreAddressList);
        }
    }

    private void removeAttachment(List<String> delFileAddress) {
        if (delFileAddress != null && !delFileAddress.isEmpty()) {
            for (String delAdr : delFileAddress) {
                clientWrapper.deleteFile(delAdr.split("#")[0]);
            }
        }
    }


}
